/*
 *	服务基础层
 */
#include "serverbasic.h"
#include <cstddef>	// NULL
#include <boost/bind.hpp>

CServerBasic::CServerBasic()
{
	m_pServerRequest = NULL;
	m_pTcpListen = NULL;
	m_nPort = 6688;
}

CServerBasic::~CServerBasic()
{
	if(NULL != m_pTcpListen)
	{
		delete m_pTcpListen;
	}
}

/*
 *	设置处理命令
 */
void CServerBasic::SetServerCommand(IServerRequest* pSvrReq)
{
	m_pServerRequest = pSvrReq;
}

/*
 *	获取服务器属性
 */
bool __stdcall CServerBasic::GetContext(ServerContext sc, void* p)
{
	return false;
}

/*
 *	查找在线的客户端
 */
bool __stdcall CServerBasic::FindClient(const char* pClientID, IClientContext** ppCC)
{
	return false;
}

void CServerBasic::Start(boost::asio::io_service* pios)
{
	if(NULL == m_pTcpListen)
	{
		m_pTcpListen = new boost::asio::ip::tcp::acceptor(*pios, 
			boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), m_nPort));
	}

	if(NULL == m_pTcpListen)
	{
		return;
	}

	// 开始监听一个新连接
	CClientContext*		pClient		= CClientContext::CreateClient(*pios);

	m_pTcpListen->async_accept(pClient->m_sock,
		boost::bind(&CServerBasic::AcceptHandler, this, boost::asio::placeholders::error, 
			pClient, pios));

	return;
}

/*
 *	接收回调函数
 */
void CServerBasic::AcceptHandler(const boost::system::error_code& ec, CClientContext* pContext, 
	boost::asio::io_service* pios)
{
	if(ec)
	{
		return;
	}
	// 设置连接超时间
#ifdef _WINDOWS_
	struct tcp_keepalive {
		ULONG onoff;
		ULONG keepalivetime;
		ULONG keepaliveinterval;
	};
	#define SIO_KEEPALIVE_VALS    _WSAIOW(IOC_VENDOR,4)

	tcp_keepalive		KeepAlive			= {0};
	tcp_keepalive		KeepAliveRread		= {0};
	DWORD				dwRet, dwRead;

	dwRead = 0;
	KeepAlive.onoff				= 1;
	KeepAlive.keepalivetime		= 60 * 1000;		//	检测的间隔时间
	KeepAlive.keepaliveinterval	= 1000;	//	重试确认断开, 重试的间隔时间, 重试5次

	dwRet = WSAIoctl(pContext->m_sock.native(), SIO_KEEPALIVE_VALS, &KeepAlive, sizeof(KeepAlive), 
		NULL, 0, 
		&dwRead, NULL, NULL);
#else
	int		keepalive		= 1;	// 开启keepalive
	int		keepidle		= 60;	// 如果60秒内没有任何数据则重试
	int		keepinterval	= 1;	// 重试时间间隔
	int		keepcount		= 5;	// 重试5次

	setsockopt(pContext->m_sock.native(), SOL_SOCKET, SO_KEEPALIVE, (void*)&keepalive, sizeof(keepalive));
	setsockopt(pContext->m_sock.native(), SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle, sizeof(keepidle));
	setsockopt(pContext->m_sock.native(), SOL_TCP, TCP_KEEPINTVL, (void*)&keepinterval, sizeof(keepinterval));
	setsockopt(pContext->m_sock.native(), SOL_TCP, TCP_KEEPCNT, (void*)&keepcount, sizeof(keepcount));
#endif
	// 开始监听新一轮
	pContext->m_sock.async_receive(boost::asio::buffer(pContext->m_recvbuf, sizeof(pContext->m_recvbuf)),
		boost::bind(&CServerBasic::RecvHandler, this, boost::asio::placeholders::error,
			pContext, pios, boost::asio::placeholders::bytes_transferred));

	Start(pios);
}

void CServerBasic::RecvHandler(const boost::system::error_code& ec, 
	CClientContext* pContext, boost::asio::io_service* pios, size_t bytes_transferred)
{
	if(ec)
	{
		pContext->m_sock.close();
		pContext->Release();
		return;
	}
	// 处理接收
	if(0 != bytes_transferred)
	{
		pContext->m_vctrecv.insert(pContext->m_vctrecv.end(), pContext->m_recvbuf, 
			pContext->m_recvbuf + bytes_transferred);
	}
	// 开始分析, 目前处理\n结束的包
	if(NULL != m_pServerRequest)
	{
		for(int i = 0; i < pContext->m_vctrecv.size(); i++)
		{
			if('\n' == pContext->m_vctrecv[i])
			{
				m_pServerRequest->RequestCommand(this, pContext, (unsigned char *)&pContext->m_vctrecv[0], i);
				pContext->m_vctrecv.erase(pContext->m_vctrecv.begin(), pContext->m_vctrecv.begin() + i + 1);
				break;
			}
		}
	}
	// 开始新一轮监听
	pContext->m_sock.async_receive(boost::asio::buffer(pContext->m_recvbuf, sizeof(pContext->m_recvbuf)),
		boost::bind(&CServerBasic::RecvHandler, this, boost::asio::placeholders::error,
		pContext, pios, boost::asio::placeholders::bytes_transferred));
}


